/* I used this monster to help QA the low level string and directory munging 
 *  code, but once I had enough stuff running that I could use the Ape for
 *  system-level testing, I stopped maintaining this.  It is quite likely that
 *  some of the routine semantics it tests for have changed.  Still, it would
 *  be of value, should mod_atom ever catch on, to revive this and do it
 *  in a more intelligent way.
 */
/*
 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved
 * Use is subject to license terms.
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Horrible mocks and fakes to support unit testing.  Mark 9:47 applies.
 */

#include <stdlib.h>
#include <regex.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>

static char * slug_val;
static int really_stat;
static int suppress_collections = 1;
static int fail_to_open_file = 0;

static void die(char * m) {
  fprintf(stderr, "UNIMPLEMENTED: %s\n", m);
  abort();
}

int suppress_writing_collections() {
  return suppress_collections;
}

void atom_filter_init(apr_pool_t * pool) {
  /* empty */
}
char * atom_filter_text_construct(apr_pool_t * pool, apr_xml_doc * doc,
				  apr_xml_elem * e, genxWriter gw) {
  die("atom_filter_text_construct");
}

apr_bucket * APR_BRIGADE_FIRST(apr_bucket_brigade * b) {
  die("APR_BRIGADE_FIRST");
}
apr_bucket * APR_BRIGADE_SENTINEL(apr_bucket_brigade * b) {
  die("APR_BRIGADE_SENTINEL");
}
apr_bucket * APR_BUCKET_NEXT(apr_bucket * b) {
  die("APR_BUCKET_NEXT");
}
int APR_BUCKET_IS_EOS(apr_bucket * b) {
  die("APR_BUCKET_IS_EOS");
}
int APR_BUCKET_IS_METADATA(apr_bucket * b) {
  die("APR_BUCKET_IS_METADATA");
}
int ap_rflush(request_rec * r) {
  die("apr_rflush");
}

int ap_rwrite(char * s, int l, request_rec * r) {
  die("ap_rwrite");
}

apr_status_t ap_get_brigade(int i, apr_bucket_brigade * b, int m, int rw,
			    int bufsize) {
  die("ap_get_brigade");
}
int ap_get_limit_req_body(request_rec * r) {
  die("ap_get_limit_req_body");
}
int apr_brigade_cleanup(apr_bucket_brigade * b) {
  die("apr_brigade_cleanup");
}
apr_bucket_brigade * apr_brigade_create(apr_pool_t * p, int alloc) {
  die("apr_brigade_create");
}
int apr_brigade_destroy(apr_bucket_brigade * b) {
  die("apr_brigade_destroy");
}
apr_status_t apr_bucket_read(apr_bucket * b, const char * * d, int * l, int m) {
  die("apr_bucket_read");
}

int apr_uuid_get(apr_uuid_t * u) {
  return APR_SUCCESS;
}

int apr_uuid_format(char * buf, apr_uuid_t * u) {
  sprintf(buf, "urn:uuid:HOO-HAH!");
  return APR_SUCCESS;
}

void ap_rputs(char * s, request_rec * r) {
  die("ap_rputs");
}
void ap_set_content_type(request_rec * r, char * s) {
  die("ap_set_content_type");
}
apr_array_header_t * apr_array_make(apr_pool_t * p, int count, int size) {
  apr_array_header_t * a = (apr_array_header_t *) malloc(sizeof(apr_array_header_t));
  a->elts= malloc(count * size * 1000);
  a->nelts = 0;
  a->size = size;
  return a;
}
void * apr_array_push(apr_array_header_t * a) {
  void * ret = (void *) (a->elts + (a->nelts * a->size));
  a->nelts++;
  return ret;
}
void * apr_palloc(apr_pool_t * p, int size) {
  return malloc(size);
}

void * apr_pcalloc(apr_pool_t * p, int size) {
  return calloc(size, 1);
}

char * apr_psprintf(apr_pool_t * p, char * fmt, ...) {
  va_list ap;

  int percents = 0;
  int i;
  char * * args;
  char * ret;
  
  /* brutal */
  for (i = 0; fmt[i]; i++)
    if (fmt[i] == '%')
      percents++;
  
  args = (char * *) malloc(percents * (sizeof(char *)));
  
  va_start(ap, fmt);
  for (i = 0; i < percents; i++)
    args[i] = va_arg(ap, char *);
  va_end(ap);

  ret = malloc(1000);
  switch (percents) {
  case 1: sprintf(ret, fmt, args[0]); break;
  case 2: sprintf(ret, fmt, args[0], args[1]); break;
  case 3: sprintf(ret, fmt, args[0], args[1], args[2]); break;
  case 4: sprintf(ret, fmt, args[0], args[1], args[2], args[3]); break;
  case 5: sprintf(ret, fmt, args[0], args[1], args[2], args[3], args[4]); break;
  default: die("apr_psprintf, more percents");
  }
  return ret;
}
char * apr_pstrcat(apr_pool_t * p, char * s1, ...) {
  die("apr_psprintf");
}
char * apr_pstrdup(apr_pool_t * p, const char * s) {
  return strdup(s);
}
int apr_stat(apr_finfo_t * finfo, char * f, int m, apr_pool_t * p) {
  struct stat s;
  int ret;

  really_stat = (strncmp(f, "/tmp/dd-", 7) == 0 ||
		 strncmp(f, "../test-pub/", 11) == 0);

  if (really_stat == 0) {
    finfo->filetype = APR_DIR;
    finfo->name = rindex(f, '/') + 1;
    return APR_SUCCESS;
  }

  ret = stat(f, &s);
  if (ret)
    return ret;

  finfo->filetype = (s.st_mode & S_IFDIR) ? APR_DIR : APR_REG;
  finfo->name = rindex(f, '/') + 1;
  finfo->mtime = s.st_mtime;
  finfo->size = s.st_size;
  return APR_SUCCESS;
}
void apr_table_set(void * t, char * k, char * v) {
  die("apr_table_set");
}  
ap_regex_t * ap_pregcomp(apr_pool_t * p, char * s, int i) {
  regex_t * re = (regex_t *) malloc(sizeof(regex_t));
  if (regcomp(re, s, REG_EXTENDED))
    die ("regcomp failed");
  return (ap_regex_t *) re;
}
char * ap_pregsub(apr_pool_t * p, char * dollars, char * orig, int nm, ap_regmatch_t * regm) {
  die("ap_pregsub");
}

int ap_regexec(ap_regex_t * re, char * str, apr_size_t nmatch,
		ap_regmatch_t * matches, int flags) {
  return regexec((regex_t *) re, str, nmatch, (regmatch_t *) matches, flags);
}

void ap_log_error(int mark, int a, int b, server_rec * s, char * fmt, ...) {
  va_list ap;

  int percents = 0;
  int i;
  char * * args;
  char * fmt_nl;
  
  /* brutal */
  for (i = 0; fmt[i]; i++)
    if (fmt[i] == '%')
      percents++;
  
  args = (char * *) malloc(percents * (sizeof(char *)));
  
  va_start(ap, fmt);
  for (i = 0; i < percents; i++)
    args[i] = va_arg(ap, char *);
  va_end(ap);
  fmt_nl = malloc(1000);
  sprintf(fmt_nl, "%s\n", fmt);
  fmt = fmt_nl;

  switch (percents) {
  case 1: fprintf(stderr, fmt, args[0]); break;
  case 2: fprintf(stderr, fmt, args[0], args[1]); break;
  case 3: fprintf(stderr, fmt, args[0], args[1], args[2]); break;
  case 4: fprintf(stderr, fmt, args[0], args[1], args[2], args[3]); break;
  case 5: fprintf(stderr, fmt, args[0], args[1], args[2], args[3], args[4]); break;
  default: die("ap_log_error, more percents");
  }
}

apr_status_t ap_xml_parse_input(request_rec * r, apr_xml_doc * * doc) {
  die("ap_xml_parse_input");
  return APR_SUCCESS;
}
apr_status_t apr_dir_make_recursive(char * name, apr_fileperms_t p,
				    apr_pool_t * pool) {
  int i;
  int slashes = 0;
  int pieces[1000];

  for (i = 0; name[i]; i++)
    if (name[i] == '/') {
      pieces[slashes++] = i;
    }

  for (i = 0; i < slashes; i++) {
    name[pieces[i]] = 0;
    mkdir(name, 0777);
    name[pieces[i]] = '/';
  }
  mkdir(name, 0777);
  return APR_SUCCESS;
}
void apr_file_close(apr_file_t * f) {
  
}
apr_status_t apr_file_open(apr_file_t * * f, char * sf, int x,
			   apr_fileperms_t perms, apr_pool_t * pool) {
  *f = NULL;
  if (fail_to_open_file) {
    fail_to_open_file = 0; /* once only */
    return -1;
  }
  else {
    /* if it's a LINK file, actually open it */
    if (strstr(sf, "/L.") != NULL) {
      FILE * fp = fopen(sf, "r");
      *f = (apr_file_t *) fp;
    }
    return APR_SUCCESS;
  }
}
apr_status_t apr_file_read(apr_file_t * f, char * buf, int * read_size) {
  if (f == NULL)
    die("apr_file_open");
  else {
    fread(buf, *read_size, 1, (FILE *) f);
  }
  
  return APR_SUCCESS;
}
apr_status_t apr_file_rename(char * from, char * to, apr_pool_t * pool) {
  die("apr_file_rename");
  return APR_SUCCESS;
}
void apr_strftime(char * buf, apr_size_t * time_len, int size, char * fmt,
		  apr_time_exp_t * times) {
  die("apr_strftime");
}
char * apr_strerror(apr_status_t status, char * buf, int size) {
  die("apr_strerror");
}
int apr_isdigit(int x) {
  return isdigit(x);
}
char * ap_make_etag(request_rec * r, int t) {
  die("ap_make_etag");
}
int apr_file_flush(apr_file_t * fp) {
  die("apr_file_flush");
}
int apr_xml_parse_file(apr_pool_t * pool, apr_xml_parser ** xp, apr_file_t * fp, int size) {
  die("apr_xml_parse_file");
}


int apr_file_remove(char * fn, apr_pool_t * p) {
  return APR_SUCCESS;
}
int apr_isxdigit(int x) {
  return isxdigit(x);
}
void * apr_table_get(void * t, char * v) {
  if (strcmp(v, "Slug") == 0)
    return slug_val;
  die("apr_table_get");
  return NULL;
}
void apr_time_exp_lt(apr_time_exp_t * tt, apr_time_t ttt) {
  struct tm * tm_p = localtime((time_t *) &ttt);
  tt->tm_year = tm_p->tm_year;
  tt->tm_mon = tm_p->tm_mon;
  tt->tm_mday = tm_p->tm_mday;
}
apr_time_t apr_time_now() {
  return time(NULL);
}
apr_status_t apr_file_write_full(apr_file_t * f, void * s,int l, int * w) {
  return APR_SUCCESS;
}

apr_status_t apr_dir_open(apr_dir_t * * dir_p, char * path, apr_pool_t * pool) {
  apr_dir_t * dir = (apr_dir_t *) malloc(sizeof(apr_dir_t));

  if (strncmp(path, "/tmp", 4) != 0 &&
      strncmp(path, "../test-pub", 10) != 0) {
    dir->dir = NULL;
    *dir_p = dir;
    return APR_SUCCESS;
  }

  dir->dir = opendir(path);
  *dir_p = dir;
  return APR_SUCCESS;
}
apr_status_t apr_dir_read(apr_finfo_t * finfo, int x, apr_dir_t * dir) {
  struct dirent * de;

  if (dir->dir == NULL)
    return -1;
  de = readdir(dir->dir);

  if (de == NULL)
    return -1;

  finfo->name = de->d_name;
  if (de->d_type == DT_DIR)
    finfo->filetype = APR_DIR;
  else
    finfo->filetype = APR_REG;
  return APR_SUCCESS;
}

void apr_dir_close(apr_dir_t * dir) {
  if (dir->dir)
    closedir(dir->dir);
}

apr_status_t apr_global_mutex_create(apr_global_mutex_t * * m,
				     char * lockname, int x, apr_pool_t * pool) {
  return APR_SUCCESS;
}

apr_status_t apr_global_mutex_lock(apr_global_mutex_t * m) {
  return APR_SUCCESS;
}

apr_status_t apr_global_mutex_destroy(apr_global_mutex_t * m) {
  return APR_SUCCESS;
}

apr_status_t apr_global_mutex_unlock(apr_global_mutex_t * m) {
  return APR_SUCCESS;
}

apr_hash_t * apr_hash_make(apr_pool_t * p) {
  apr_hash_t * h = (apr_hash_t *) malloc(sizeof(apr_hash_t));
  h->count = 0;
  return h;
}
void * apr_hash_get(apr_hash_t * h, void * k, int l) {
  int i;
  for (i = 0; i < h->count; i++)
    if (strcmp((char *) k, h->keys[i]) == 0)
      return h->values[i];

  return NULL;
}
void apr_hash_set(apr_hash_t * h, void * k, int l, void * v) {
  h->keys[h->count] = strdup((char *) k);
  h->values[h->count] = strdup((char *) v);
  h->count++;
}



static int passed;
static int failed;

static void assertEq(char * label, int wanted, int got) {
  if (wanted == got) {
    printf(".");
    passed++;
  }
  else {
    printf("\n%s: wanted %d got %d\n", label, wanted, got);
    failed++;
  }
}
static void assertNonZero(char * label, int val) {
  if (val) {
    printf(".");
    passed++;
  }
  else {
    printf("\n%s: wanted non-zero\n", label);
    failed++;
  }
}


static void assertStrEq(char * label, char * wanted, char * got) {
  if (wanted == got || (wanted != NULL && strcmp(wanted, got) == 0)) {
    printf(".");
    passed++;
  }
  else {
    failed++;
    if (wanted == NULL) {
      printf("\n%s: wanted NULL got %x\n", label, got);
    }
    else {
      if (got == NULL)
	got = "[NULL]";
      printf("\n%s: wanted %s got %s\n", label, wanted, got);
    }
  }
}

/*****************************/
/* Unit tests from here down */

static void test_prefix() {
  assertStrEq("simple", "foo", is_prefix("barfoo", "bar"));
  assertStrEq("long prefix", NULL, is_prefix("a", "abcdef"));
  assertStrEq("not prefix", NULL, is_prefix("abcd", "x"));
  assertStrEq("exact", "", is_prefix("abcd", "abcd"));
  assertStrEq("empty", "foo", is_prefix("foo", ""));
}

static void test_pub_finder() {
  cmd_parms * cmd = (cmd_parms *) malloc(sizeof(cmd_parms));
  char * paths[] = { "/pub1", "/pub2/variant", "/secondpub", "/third/odd/pub",
		     "/thirty-nine" };
  char * titles[] = { "P1 title", "variant title", "secondpub title",
		      "third/odd title", "39 title" };
  char * dirs[] = { "/home1", "home2/variant", "/secondpub-home", "/home3",
		    "/39" };
  char * authors[] = { "Smith", "Jones", "Brown", "White", "Miller" };
  int i;
  pub_t * p;
  char d_dir[1000];
  char * dir_args[4];

  pre_config(NULL, NULL, NULL);

  for (i = 0; i < 5; i++) {
    dir_args[0] = paths[i];
    dir_args[1] = dirs[i];
    dir_args[2] = titles[i];
    dir_args[3] = authors[i];
    atompub_directive(cmd, NULL, 4, (char * const *) dir_args);
  }

  /* setting up for another test later */
  sprintf(d_dir, "/tmp/dd-%d", time(NULL));
  dir_args[0] = "/name-test";
  dir_args[1] = d_dir;
  dir_args[2] = "Name Testing";
  dir_args[3] = "Tim";
  atompub_directive(cmd, NULL, 4, (char * const *) dir_args);

  /* and another */
  /*
  dir_args[0] = "/iter-test";
  dir_args[1] = "../test-pub";
  dir_args[2] = "Iterator Testing";
  dir_args[3] = "T T T T T";
  atompub_directive(cmd, NULL, 4, (char * const *) dir_args);
  */

  post_config(NULL, NULL, NULL, NULL);
  for (i = 0; i < 5; i++) {
    p = find_pub(paths[i]);
    if (p) {
      assertStrEq(titles[i], paths[i], p->path);
      assertStrEq(titles[i], titles[i], p->title);
      if (dirs[i] == NULL)
	assertStrEq(titles[i], paths[i], p->dir);
      else
	assertStrEq(titles[i], dirs[i], p->dir);
    }
    else
      assertStrEq(titles[i], "Something non-nil", (char *) p);
  }

  p = find_pub("/pub2/variant/swizzle");
  if (p)
    assertStrEq("find /pub2 A",  p->path, "/pub2/variant");
  else
    assertStrEq("find /pub2 B", (char *) p, "something non-NULL");

  assertStrEq("/pub", NULL, (char *) find_pub("/pub"));
  
  assertStrEq("MISS1", NULL, (char *) find_pub("/pub3"));
  assertStrEq("MISS2", NULL, (char *) find_pub("/home1/"));
  assertStrEq("MISS3", NULL, (char *) find_pub("xyz"));
}

/* test that the REs work */
static void test_pub_contents() {
  /* contents are set up test_pub_finder */
  /* /pub2/variant, "variant title", NULL */
  pub_t * pub = find_pub("/pub2/variant");
  ap_regmatch_t * matches = (ap_regmatch_t *) malloc(1000);
  int ret;

  /* html */
  assertEq("pub2...index.html", 0,
	   ap_regexec(pub->html_re, "/pub2/variant/pub/index.html", 5, matches, 0));
  assertNonZero("pub2...foo", 
		ap_regexec(pub->html_re, "/pub2/variant/pub/foo", 5, matches, 0));
  assertNonZero("pub2...foo.html", 
		ap_regexec(pub->html_re, "/pub2/variant/pub/foo.html", 5, matches, 0));
  assertEq("real html", 0,
	   ap_regexec(pub->html_re, "/pub2/variant/pub/2007/05/11/foo.html", 5, matches, 0));
  assertEq("real xhtml", 0,
	   ap_regexec(pub->html_re, "/pub2/variant/pub/2007/05/11/foo.xhtml", 5, matches, 0));
  assertEq("real text", 0,
	   ap_regexec(pub->html_re, "/pub2/variant/pub/2007/05/11/foo.text", 5, matches, 0));

  /*feeds*/
  assertEq("public feed", 0,
	   ap_regexec(pub->feed_re, "/pub2/variant/pub/feed", 5, matches, 0));
  assertEq("entries collection", 0,
	   ap_regexec(pub->collection_re, "/pub2/variant/atom/e/entries/collection", 5, matches, 0));
  assertNonZero("bogus entries  collection",
	   ap_regexec(pub->feed_re, "/pub2/variant/atom/e/bogus/foo-foo", 5, matches, 0));
  assertEq("media-link collection", 0,
	   ap_regexec(pub->collection_re, "/pub2/variant/atom/m/media/collection", 5, matches, 0));

  assertNonZero("non-feed", 
		ap_regexec(pub->html_re, "/pub2/variant/pub/x/feed", 5, matches, 0));

  /* entries */
  assertEq("atom entries", 0,
	   ap_regexec(pub->entry_re,
		      "/pub2/variant/atom/e/entries/2007/05/12/fioveef2e23g",
		      5, matches, 0));

  assertEq("media-link entries", 0,
	   ap_regexec(pub->entry_re,
		      "/pub2/variant/atom/m/media/2007/05/12/fioveef2e23g",
		      5, matches, 0));

  assertNonZero("non-entries", 
		ap_regexec(pub->html_re,
			   "/pub2/variant/atom/m/media/2x07/05/12/fioveef2e23g",
			   5, matches, 0));
  
  /* service doc */
  assertStrEq("service doc", "/pub2/variant/atom/service", pub->service_doc);
}

test_decode_slug() {
  char i1[] = { 'f', 'o', 'o', 0xff, 0xff, 0xff, 'b', 'a', 'r', 0 };
  char i2[] = { 'S', 0xc3, 0xa8, 't', 'e', 0 };
  char i3[] = { 'S', 0xc3, 0xa8, 't', 'e',
		0xe2, 0x99, 0xaa, 'X', 0 };
  char o3[] = { 'S', 0XC3, 0XA8, 't', 'e',
		'-', 'X', 0 };
  char i4[] = { 0xff, 0xff, 0xff, 0 };
  char * in[] = {
    "foo!bar",
    "   foo_bar**baz",
    "foo.bar",
    i1,
    i2,
    i3,
    i4,
    NULL
  };
  char * out[] = {
    "foo-bar",
    "foo_bar-baz",
    "foo-bar",
    "foobar",
    "S%C3%A8te",
    "S%C3%A8te-X",
    NULL
  };
  int i;

  for (i = 0; in[i]; i++) {
    char msg[1000];
    sprintf(msg, "decode [%s]", in[i]);
    assertStrEq(msg, out[i], decode_slug(in[i], NULL));
  }
}

test_make_filenames() {
  /*   atompub_directive("/name-test", "Name testing", ddir); */
  pub_t * pub = find_pub("/name-test");
  request_rec r;
  char * filename;
  char * uri_path;
  char want_filename[1000];
  char want_uri[1000];
  struct tm * tm_p;
  time_t now;
  char yyyymmdd[100];
  char dir[100];
  char * digs;
  char * html_name;
  char want_html_name[1000];
  entry_t entry;
  apr_xml_doc xml;
  apr_xml_elem root, title;
  apr_text ttext;
  apr_text_header htext;
  apr_array_header_t ns_h;
  char * ns_names[] = { ATOM_NS, NULL };
  ns_h.nelts = 1;
  ns_h.elts = (char *) ns_names;

  xml.namespaces = &ns_h;
  ttext.text = "Name Testing";
  ttext.next = NULL;
  htext.first = htext.last = &ttext;
  
  xml.root = &root;
  root.first_child = &title;
  title.next = NULL;
  title.first_cdata = htext;
  title.ns = 0;
  title.name = "title";

  r.uri = "/name-test/atom/e/entries/collection";
  r.parsed_uri.port_str = NULL;
  r.hostname = "l337.com";
  slug_val = NULL;
  now = time(NULL);
  tm_p = localtime(&now);
  sprintf(yyyymmdd, "%04d/%02d/%02d", tm_p->tm_year + 1900 , tm_p->tm_mon + 1,
	  tm_p->tm_mday);
  atom_dir(apr_psprintf(NULL, "%s/atom/e/entries/%s", pub->dir, yyyymmdd), NULL);
  sprintf(want_filename, "%s/atom/e/entries/%s/Name-Testing", pub->dir, yyyymmdd);
  sprintf(want_uri, "%s/atom/e/entries/%s/Name-Testing", pub->path, yyyymmdd);
  sprintf(want_html_name, "%s/pub/e/entries/%s/Name-Testing", pub->path, yyyymmdd);
  sprintf(dir, "%s/atom/e/entries/%s", pub->dir, yyyymmdd);
  entry.pub = pub;
  entry.xml = &xml;
  entry_names(&r, dir, &entry);
  // entry_names(&r, dir, pub->title, &filename, &uri_path, &html_name);
  assertStrEq("filename", want_filename, entry.filename);
  assertStrEq("uri path", want_uri, entry.uri);
  assertStrEq("html file", want_html_name, entry.html_name);
  fail_to_open_file = 1;
  entry_names(&r, dir, &entry);
  digs = is_prefix(entry.filename, want_filename) + 1;
  if (!digs)
    assertStrEq("collided fname prefix", want_filename, digs);
  while (*digs)
    assertNonZero("numeric digit", isdigit(*digs++));
  fail_to_open_file = 0;
  sprintf(want_uri, "rm -r %s", pub->dir);
  system(want_uri);
}

test_iterator() {
  void * iter;
  char * problem;
  char * got;
  int i;

  char * wanted[] = {
    "../test-pub/2007/05/28/ape-55129",
    "../test-pub/2007/05/29/ape-60325",
    "../test-pub/2007/05/29/ape-29600",
    "../test-pub/2007/05/29/ape-97654",
    "../test-pub/2007/05/29/ape-90703",
    "../test-pub/2007/05/29/ape-9282",
    "../test-pub/2007/05/29/ape-80146",
    "../test-pub/2007/05/29/ape-31157",
    "../test-pub/2007/05/29/ape-46153",
    "../test-pub/2007/05/29/ape-96004",
    "../test-pub/2007/05/29/ape-22534",
    "../test-pub/2007/05/29/ape-94008",
    "../test-pub/2007/05/29/ape-37247",
    "../test-pub/2007/05/29/ape-6893",
    "../test-pub/2007/05/29/ape-43486",
    "../test-pub/2007/05/28/ape-76574",
    "../test-pub/2007/05/28/ape-25460",
    "../test-pub/2007/05/28/ape-35741",
    "../test-pub/2007/05/28/ape-91837",
    "../test-pub/2007/05/28/ape-16275",
    "../test-pub/2007/05/28/ape-86457",
    "../test-pub/2007/05/28/ape-75486",
    "../test-pub/2007/05/28/ape-17437",
    "../test-pub/2007/05/28/ape-55661",
    "../test-pub/2007/05/28/ape-76539",
    NULL
  };

  problem = atom_iter_new(NULL, "../test-pub/", &iter);
  assertStrEq("new iter", NULL, problem);

  for (problem = atom_iter_next(iter, &got), i = 0;
       wanted[i] && (!problem);
       problem = atom_iter_next(iter, & got), i++) {
    char label[100];
    sprintf(label, "iter test %d", i);
    assertStrEq(label, wanted[i], got);
  }
  
}

int main(int argc, char * argv[])
{
  passed = failed = 0;
  printf("Test: ");
  really_stat = 0;
  test_prefix();
  test_pub_finder();
  test_pub_contents();
  test_decode_slug();
  test_make_filenames();
  test_iterator();
  printf("\n");
  printf("%d assertions, %d failed.\n", passed + failed, failed);
  return failed;
}



